'use strict';

/* Services */


// Demonstrate how to register services
// In this case it is a simple value service.
angular.module('myApp.services', []).
        value('version', '0.1').
        factory('serviceMenu', function() {
            return {
                    beforeLogin : [
                        {title: 'Login' , link : '#/login'},
                        {title: 'Create account' , link : '#/createaccount'}
                    ],
                    afterLogin : [
                        {title: 'New Game' , link : '#/game/play/owner'},
                        {title: 'Players online' , link : '#/game/players'},
                        {title: 'Logout' , link : '#/logout'},
                    ],
                    game :[
                        {title: 'Quit game' , link : '#/game/quit'}
                    ]
                }
        }).
        factory('serviceStorage', function() {
            return window.localStorage;
        }).
        factory('serviceFirebase', function() {
            return new Firebase('https://slaszu.firebaseio.com/');
        }).
        factory('common', function () {
           return {
               prepareEmail : function(email) {
                    return email.replace(/\./g,'_');
                },
                
                prepareCallback : function(callback) {
                     if (typeof callback !== 'function') {
                        callback = function (data) {
                            console.log(data);
                        };
                    }
                    return callback;
                }
           } 
        }).
        factory('serviceFirebaseUsers', ['serviceFirebase', 'common', function (ref, Common) {
            var refUser     = ref.child('users');
            var refActive   = ref.child('active_users');
            return {
                
                createAccount : function(user, callbackOk, callbackError) {
                    
                    var email = Common.prepareEmail(user.email);
                    var newUser = refUser.child(email);
                    
                    newUser.once('value', function(snapshot) {
                        var data = snapshot.val();
                        if (data) {
                            callbackError();
                        } else {
                            newUser.set(user, callbackOk);
                        }
                    });
                },
                
                getUserByEmail : function(email, callback) {
                    var callback = Common.prepareCallback(callback);
                    var email = Common.prepareEmail(email);
                    
                    var refUserOne = refUser.child(email);
                    refUserOne.once('value', function(snapshot) {
                        callback(snapshot.val(), refUserOne);
                    });
                },
                
                setUserActive : function(user, callback, invitationCallback) {
                    var callback = Common.prepareCallback(callback);
                    var email = Common.prepareEmail(user.email);
                    
                    var refUserActive = refActive.child(email);
                    
                    // disconnect cleaner
                    refUserActive.onDisconnect().remove();
                    
                    // invitation handler
                    refUserActive.on('value', function(snapshot) {
                        if (typeof invitationCallback !== 'undefined') {
                            invitationCallback(snapshot.val());
                        }
                    });
                    
                    // set user in active section
                    refUserActive.set(user, function(error) {
                        callback(error, refUserActive);
                    });
                },
                
                setUserInvitation : function(userTo, userFrom, callback) {
                    var callback = Common.prepareCallback(callback);
                    var email = Common.prepareEmail(userTo.email);
                    
                    var refUserActive = refActive.child(email);
                    refUserActive.update({invitedUser: userFrom}, callback);
                },
                
                clearUserInvitation : function (userTo, callback) {
                    var callback = Common.prepareCallback(callback);
                    var email = Common.prepareEmail(userTo.email);
                    
                    var refUserActive = refActive.child(email);
                    refUserActive.update({invitedUser: null}, callback);
                },
                
                getActiveUsersRef : function() {
                    return refActive;
                },
                
                setPoints : function (userTo, points, callback) {
                    var callback = Common.prepareCallback(callback);
                    var email = Common.prepareEmail(userTo.email);
                    
                    var refUserThis = refUser.child(email);
                    refUserThis.update({points: points}, callback );
                },
                
                setWin : function (userTo, callback) {
                    this.setPoints(userTo, userTo.points + 5, callback);
                },
                
                setLose : function (userTo, callback) {
                    this.setPoints(userTo, userTo.points - 5, callback);
                },
                
                setWinAndLose : function (winUser, loseUser, callback) {
                    var t = this;
                    
                    t.setWin(winUser, function () {
                        t.setLose(loseUser, callback);
                    });
                }
            }
        }]).
        factory('serviceFirebaseGames', ['serviceFirebase', 'common', function (ref, Common) {
            var refGames     = ref.child('games');

            return {
               
                createGame : function(ownerUser, game, callback) {
                    
                    var callback = Common.prepareCallback(callback);
                    var email = Common.prepareEmail(ownerUser.email);
                    
                    var refGame = refGames.child(email);
                    
                    refGame.on('value', function(snapshot) {
                        var data = snapshot.val();
                        if (data && data.playerUser && !data.loserUser) {
                            refGame.onDisconnect().cancel();
                            refGame.onDisconnect().update({
                                'loserUser' : ownerUser
                            });
                        } else {
                            refGame.onDisconnect().cancel();
                            refGame.onDisconnect().remove();
                        }
                    });
                    refGame.set(game, callback(refGame));
                    
                },
                
                joinGame : function(ownerUser, joinUser, callback) {
                    var callback = Common.prepareCallback(callback);
                    var email = Common.prepareEmail(ownerUser.email);
                    var refGame = refGames.child(email);
                    
                    refGame.on('value', function(snapshot) {
                        var data = snapshot.val();
                        if (data && data.ownerUser && !data.loserUser) {
                            refGame.onDisconnect().cancel();
                            refGame.onDisconnect().update({
                                'loserUser' : joinUser
                            });
                        } else {
                            refGame.onDisconnect().cancel();
                            refGame.onDisconnect().remove();
                        }
                    });
                    
                    refGame.update({playerUser : joinUser}, callback(refGame));
                },
                
                getGameRef : function(ownerEmail) {
                    var email = Common.prepareEmail(ownerEmail);
                    var refGame = refGames.child(email);
                    return refGame;
                }
            }
        }]);
